-- «¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»«¦•»
{-
    $Author$
    $Revision$
    $Id$
    $Date$
-}

--- Contributed by Daniel Gronau

protected package frege.prelude.Floating where

import frege.prelude.PreludeBase
import frege.prelude.Math()

class  Floating Real a => a where
    pi                  :: a
    exp, log, sqrt      :: a -> a
    (**), logBase       :: a -> a -> a
    sin, cos, tan       :: a -> a
    asin, acos, atan    :: a -> a
    sinh, cosh, tanh    :: a -> a
    asinh, acosh, atanh :: a -> a
    x ** y              =  exp (log x * y)
    logBase x y         =  log y / log x
    tan  x              =  sin  x / cos  x
    tanh x              =  sinh x / cosh x

instance Floating Double where
    pi = Math.pi
    asinh x = Floating.log (x + Floating.sqrt (1.0 + x*x))
    acosh x = Floating.log (x + (x + 1.0) * Floating.sqrt ((x - 1.0)/(x + 1.0)))
    atanh x = 0.5 * Floating.log ((1.0 + x) / (1.0 - x))
    -- the following 3 can't be inherited because Double.**, Double.tan and Double.tanh
    -- already exist as native functions and would be inherited from there
    x ** y              =  exp (log x * y)
    tan  x              =  sin  x / cos  x
    tanh x              =  sinh x / cosh x

instance Floating Float where
    pi = Math.pi.float
    -- the following 3 can't be inherited because Float.**, Float.tan and Float.tanh
    -- already exist as native functions and would be inherited from there
    x ** y   = exp (log x * y)
    tan  x   = sin  x / cos  x
    tanh x   = sinh x / cosh x
    acos  f  = (Float.acos f).float
    asin  f  = (Float.asin f).float
    atan  f  = (Float.atan f).float
    cosh  f  = (Float.cosh f).float
    sinh  f  = (Float.sinh f).float
    sqrt  f  = (Float.sqrt f).float
    cos  f   = (Float.cos f).float
    exp  f   = (Float.exp f).float
    log  f   = (Float.log f).float
    sin  f   = (Float.sin f).float
    asinh x = Floating.log (x + Floating.sqrt (1.0f + x*x))
    acosh x = Floating.log (x + (x + 1.0f) * Floating.sqrt ((x - 1.0f)/(x + 1.0f)))
    atanh x = 0.5f * Floating.log ((1.0f + x) / (1.0f - x))

